﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Activation;
using Business.Common.DataDictionary;
using Business.Common.Exception;
using Business.Common.QueryModel;
using Business.DataAccess.Repository.Inventory;
using Business.DataAccess.Repository.Warehouse;
using Business.DataAccess.Repository.Wms;
using Business.Domain.Inventory;
using Business.Domain.Warehouse;
using Business.Domain.Wms;
using Business.Service.Contract;
using Framework.Core.Collections;
using Business.Component;

namespace Business.Service
{
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    public class InboundService : IInboundService
    {
        #region inbound plan
        public List<InboundPlan> GetInboundPlanByQuery(Query query)
        {
            try
            {
                var repository = new InboundPlanRepository();
                return CollectionHelper.ToList(repository.GetListByQuery(query));
            }
            catch (Exception ex)
            {
                ServiceExceptionHelper.ThrowServiceException(ex);
            }

            return new List<InboundPlan>();
        }

        public List<InboundPlan> GetInboundPlanByPagerQuery(PagerQuery query, out int qty)
        {
            qty = 0;
            try
            {
                var repository = new InboundPlanRepository();
                return CollectionHelper.ToList(repository.GetByPager(query, out qty));
            }
            catch (Exception ex)
            {
                ServiceExceptionHelper.ThrowServiceException(ex);
            }

            return new List<InboundPlan>();
        }

        public InboundPlan GetInboundPlanByNumber(string warehouseCode, string planNumber)
        {
            try
            {
                var repository = new InboundPlanRepository();
                return repository.GetByBillNumber(warehouseCode, planNumber);
            }
            catch (Exception ex)
            {
                ServiceExceptionHelper.ThrowServiceException(ex);
            }

            return null;
        }

        public InboundPlan CreateInboundPlan(InboundPlan inboundPlan)
        {
            var planRepository = new InboundPlanRepository();
            try
            {
                if (inboundPlan.Details == null || inboundPlan.Details.Count == 0)
                    BusinessExceptionHelper.ThrowBusinessException("4002");

                var planDetailRepository = new InboundPlanDetailRepository();

                planDetailRepository.BeginTransaction();
                inboundPlan.PlanNumber = BillManager.GetNewBillNumber(inboundPlan.WarehouseId, BillType.InboundPlan);
                int planId = planRepository.Create(inboundPlan);
                if (planId <= 0)
                    BusinessExceptionHelper.ThrowBusinessException("4003");

                inboundPlan.PlanId = planId;
                foreach (var planDetail in inboundPlan.Details)
                {
                    planDetail.PlanId = planId;
                    planDetailRepository.Create(planDetail);
                }

                planDetailRepository.CommitTransaction();
                return inboundPlan;
            }
            catch (Exception ex)
            {
                planRepository.RollBackTransaction();
                ServiceExceptionHelper.ThrowServiceException(ex);
            }

            return null;
        }

        public bool UpdateInboundPlan(InboundPlan inboundPlan)
        {
            var planRepository = new InboundPlanRepository();
            try
            {
                if (inboundPlan.Details == null || inboundPlan.Details.Count == 0)
                    BusinessExceptionHelper.ThrowBusinessException("4004");

                var planDetailRepository = new InboundPlanDetailRepository();
                planRepository.BeginTransaction();
                bool updateResult = planRepository.Update(inboundPlan);
                if (!updateResult)
                    BusinessExceptionHelper.ThrowBusinessException("4005");

                foreach (var planDetail in inboundPlan.Details)
                {
                    updateResult = planDetailRepository.Update(planDetail);
                    if (!updateResult)
                        BusinessExceptionHelper.ThrowBusinessException("4006");
                }
                planRepository.CommitTransaction();
                return true;
            }
            catch (Exception ex)
            {
                planRepository.RollBackTransaction();
                ServiceExceptionHelper.ThrowServiceException(ex);
            }

            return false;
        }

        public bool RevokeInboundPlan(long inboundPlanId)
        {
            var repository = new InboundPlanRepository();
            InboundPlan inboundPlan = repository.Get(inboundPlanId);

            if (inboundPlan.BillStatus != (int)InboundPlanStatus.Created &&  inboundPlan.BillStatus != (int)InboundPlanStatus.Modified && inboundPlan.BillStatus != (int)InboundPlanStatus.Confirmed)
                BusinessExceptionHelper.ThrowBusinessException("4007");

            inboundPlan.BillStatus = (int) InboundPlanStatus.Cancelled;
            return repository.Update(inboundPlan);
        }

        public bool ConfirmInboundPlan(int warehouseId, long planId, int userId)
        {
            return BillManager.Confirm(warehouseId, BillType.InboundPlan, planId, userId);
        }

        public int AddInboundPlanDetail(long inboundPlanId, InboundPlanDetail planDetail)
        {
            throw new NotImplementedException();
        }

        public bool UpdateInboundPlanDetail(InboundPlanDetail planDetail)
        {
            throw new NotImplementedException();
        }

        public bool RemoveInboundPlanDetail(long planDetailId)
        {
            throw new NotImplementedException();
        }

        public bool ImportInboundPlan(string clientCode, string message)
        {
            throw new NotImplementedException();
        }

        public List<InboundPlanDetail> GetInboundPlanDetails(long planDetailId)
        {
            throw new NotImplementedException();
        }

        public List<InboundBill> GetInboundBillsByPlan(long planDetailId)
        {
            throw new NotImplementedException();
        }

        public List<SerialNumber> GetSerialNumbersByPlan(long planDetailId)
        {
            throw new NotImplementedException();
        }
        #endregion
    }
}
